package com.atguigu.lambda;

import com.atguigu.lambda.entity.Person;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author Jungle
 * @create 2024-01-06 22:23
 */
public class StreamDemo {

    static List<Person> persons = List.of(
            new Person("陆荣", "女", 21),
            new Person("谭莉", "男", 20),
            new Person("周建平", "男", 19),
            new Person("金颖", "女", 21),
            new Person("周楠", "男", 16)
    );
    private static String[] buffer = new String[1];

    public static void main(String[] args) {
        StreamDemo streamDemo = new StreamDemo();
        System.out.println("1111");
        streamDemo.a();
        System.out.println("222222");
        streamDemo.b("aaa");

    }

    public  void a() {
        String s = "aaaa";
        System.out.println(s+"做完事了");
        // b("aaa");
        buffer[0] = s;
    }

    private  void b(String arg) {
        arg=buffer[0];

        //@formatter:off  线程暂停一会儿
        try { TimeUnit.SECONDS.sleep( 5 ); } catch (InterruptedException e) { e.printStackTrace();}
        //@formatter:on
        System.out.println(arg);
    }


    public static void opt(String[] args) {
        //
        // Map<String,Person> collect =
        persons.stream()
                .filter(s -> s.getAge() > 15)
                .peek(System.out::println);
                // .collect(Collectors.toMap(Person::getGender, Function.identity(), (Person p1, Person p2) -> Person.builder()
                //         .name(p1.getName())
                //         .gender(p1.getGender())
                //         .age(p1.getAge()+p2.getAge())
                //         .build()));
        // .collect(Collectors.groupingBy(Person::getGender));

        // System.out.println(collect);
    }


    /**
     * 流处理
     */
    public static void handler(String[] args) {
        /**
         * ● filter：过滤；  挑出我们用的元素
         * ● map： 映射： 一一映射，a 变成 b
         *   ○ mapToInt、mapToLong、mapToDouble
         * ● flatMap：打散、散列、展开、扩维：一对多映射
         */


        //  1、挑出 年龄大于18岁的人  拿到集合流其实就是拿到集合的深拷贝的值，流的所有操作都是流的元素的引用
        //     filter、map、flatMap  非并发流--流里面的每一个元素都完整走—个流水线，才能轮到下一个元素;
        // 第一个元素流经所有的管道处理后，下一个元素才能继续执行完管道流程
        // 声明式：基于事件机制回调
        // 如果没有终止操作程序不会执行

        // distinct、 sorted.peek、 limit、 skip、 takeWhile
        persons.stream().
                limit(3)
                .filter(person ->
                { //程序员不用自己调用，而是发生这个事情的时候系统调用
                    // System.out.println("filter:" + person.hashCode());
                    return person.getAge() > 15;
                })  //挑出年龄大于18的
                .peek(p -> System.out.println("filter  peek=>" + p)) //查看元素，不操作元素
                .map(person -> {
                    // System.out.println("map:" + person.hashCode());
                    return person.getName();
                })  //拿到所有人的姓名
                .peek(p -> System.out.println("map peek:" + p))
                .flatMap(StreamDemo::getStream)  //扁平化处理
                .distinct() //去重
                .sorted(String::compareTo)  //排序
                .forEach(System.out::println);


        System.out.println("============filter===========");

        long[] longs = IntStream.range(1, 5).asLongStream()
                // .peek(System.out::println)
                .filter(i -> i > 2)  //无条件遍历流中的没有个元素
                .toArray();

        for (long l : longs) {
            System.out.println(l);
        }
        System.out.println("============takeWhile===========");

        long[] array = IntStream.range(1, 5).asLongStream()
                // .peek(System.out::println)
                // .filter(i -> i > 2)
                .takeWhile(i -> i < 2)  //当满足条件，拿到这个元素，不满足直接结束操作 //从左边向右边操作，一旦不满足直接结束
                .toArray();


        for (long l : array) {
            System.out.println(l);
        }
    }

    /**
     * 获取流
     */
    private static Stream<String> getStream(String name) {
        return name.codePoints()
                .mapToObj(c -> String.valueOf((char) c))
                .toList().stream();
    }


    public static void createStream(String[] args) {
        //流的三大部部分:
        //1、数据流2、N个中间操作﹑3、—个终止操作

        // 1、数据流(创建)
        Stream<Integer> stream = Stream.of(1, 2, 3);
        Stream<Integer> stream1 = Stream.of(2, 4, 3);
        Stream<Integer> concat = Stream.concat(stream, stream1);
        // concat.forEach(System.out::println);
        Stream<Object> build = Stream.builder().add("11").add("22").build();
        build.forEach(System.out::println);


        // 2、从集合容器中获取到这个流List,Set,Map
        List<Integer> integers = java.util.List.of(1, 2);
        Stream<Integer> stream2 = integers.stream();
        Set<Integer> integers1 = Set.of(1, 2);
        Stream<Integer> stream3 = integers1.stream();
        Map<Object, Object> of = Map.of("k1", "v1", "k2", "v2");
        Stream<Object> keyStream = of.keySet().stream();
        keyStream.forEach(System.out::println);
        Stream<Object> valueStream = of.values().stream();
        valueStream.forEach(System.out::println);


        // List<Object> objects = Collections.synchronizedList(new ArrayList<>());

        //有状态数据将产生并发安全问题,千万不要这么写?
        // 流的所有操作都是无状态; 数据状态仅在此函数内有效，不溢出到函数外
        System.out.println(Thread.currentThread().getName());
        //流是并发还是不并发?和for有啥区别?
        long count = IntStream.range(1, 6)
                .parallel()
                .filter(i -> {
                    // objects.add(i);
                    System.out.println("filter线程" + Thread.currentThread().getName());
                    System.out.println("正在filter：" + i);
                    return i > 2;
                }).count();
        System.out.println("数量==》" + count);


    }


    public static void example(String[] args) {
        List<Integer> list = Stream.iterate(1, i -> i + 1).limit(10).toList();

        // 1、挑出最大的偶数
        int max = 0;
        for (Integer integer : list) {
            if (integer % 2 == 0) {
                // 如果是偶数和max进行比较
                max = integer > max ? integer : max;
            }
        }
        System.out.println("最大的偶数==》" + max);

        // 流特性
        //   1） 流是lazy，不用  方法就不会被调用
        //   2、使用StreamApi
        list.stream().filter(item -> {
            // System.out.println("正在filter:"+item);
            return item % 2 == 0;
        }).max(Integer::compareTo).ifPresent(System.out::println);

    }
}
